Passed
Push — feature/93-optimize-scrutinize... ( acdaff...a7e399 )
by Kevin Van
02:57
created

Search   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 188
dl 0
loc 241
rs 10
c 0
b 0
f 0

9 Functions

Rating   Name   Duplication   Size   Complexity  
A searchData 0 5 1
B componentDidMount 0 55 1
A rebuildIndex 0 39 1
A handleSubmit 0 2 1
A renderQueryResults 0 19 1
A render 0 27 4
A renderQueryResultsCaption 0 28 1
A renderQueryResultItem 0 11 1
A renderForm 0 20 1
1
import React, { Component } from "react"
2
import Axios from "axios"
3
import { Link } from "gatsby"
4
5
import * as JsSearch from "js-search"
6
7
import "./search-container.scss"
8
9
class Search extends Component {
10
  state = {
11
    articleList: [],
12
    teamList: [],
13
    playerList: [],
14
    staffList: [],
15
    eventList: [],
16
    search: [],
17
    searchResults: [],
18
    isLoading: true,
19
    isError: false,
20
    searchQuery: ``,
21
  }
22
  /**
23
   * React lifecycle method to fetch the data
24
   */
25
  async componentDidMount() {
26
    Axios.get(`https://api.kcvvelewijt.be/jsonapi/node/article?sort=-created`)
27
      .then(result => {
28
        const articleData = result.data.data
29
        console.log(`Articles loaded: ${articleData.length}`)
30
        this.setState({ articleList: articleData })
31
32
        return Axios.get(
33
          `https://api.kcvvelewijt.be/jsonapi/node/team?sort=title`
34
        )
35
      })
36
      .then(result => {
37
        const teamData = result.data.data
38
        console.log(`Teams loaded: ${teamData.length}`)
39
        this.setState({ teamList: teamData })
40
41
        return Axios.get(
42
          `https://api.kcvvelewijt.be/jsonapi/node/player?sort=title`
43
        )
44
      })
45
      .then(result => {
46
        const playerData = result.data.data
47
        console.log(`Players loaded: ${playerData.length}`)
48
        this.setState({ playerList: playerData })
49
50
        return Axios.get(
51
          `https://api.kcvvelewijt.be/jsonapi/node/staff?sort=title`
52
        )
53
      })
54
      .then(result => {
55
        const staffData = result.data.data
56
        console.log(`Staff loaded: ${staffData.length}`)
57
        this.setState({ staffList: staffData })
58
59
        return Axios.get(
60
          `https://api.kcvvelewijt.be/jsonapi/node/event?sort=title`
61
        )
62
      })
63
      .then(result => {
64
        const eventData = result.data.data
65
        console.log(`Events loaded: ${eventData.length}`)
66
        this.setState({ eventList: eventData })
67
68
        setTimeout(() => {
69
          this.rebuildIndex()
70
        }, 250)
71
      })
72
      .catch(err => {
73
        this.setState({ isError: true })
74
        console.log(`====================================`)
75
        console.log(`Something bad happened while fetching some data\n${err}`)
76
        console.log(`====================================`)
77
      })
78
  }
79
  /**
80
   * rebuilds the overall index based on the options
81
   */
82
  rebuildIndex = () => {
83
    const {
84
      articleList,
85
      teamList,
86
      playerList,
87
      staffList,
88
      eventList,
89
    } = this.state
90
    const dataToSearch = new JsSearch.Search(`id`)
91
    /**
92
     *  defines a indexing strategy for the data
93
     * more more about it in here https://github.com/bvaughn/js-search#configuring-the-index-strategy
94
     */
95
    dataToSearch.indexStrategy = new JsSearch.PrefixIndexStrategy()
96
    /**
97
     * defines the sanitizer for the search
98
     * to prevent some of the words from being excluded
99
     *
100
     */
101
    dataToSearch.sanitizer = new JsSearch.LowerCaseSanitizer()
102
103
    /**
104
     * defines the search index
105
     * read more in here https://github.com/bvaughn/js-search#configuring-the-search-index
106
     */
107
    dataToSearch.searchIndex = new JsSearch.TfIdfSearchIndex(`id`)
108
    dataToSearch.addIndex([`attributes`, `body`, `processed`])
109
    dataToSearch.addIndex([`attributes`, `title`])
110
    dataToSearch.addDocuments(articleList)
111
    console.log(`articleList added - ${articleList.length} articles indexed`)
112
    dataToSearch.addDocuments(teamList)
113
    console.log(`teamList added - ${teamList.length} articles indexed`)
114
    dataToSearch.addDocuments(playerList)
115
    console.log(`playerList added - ${playerList.length} articles indexed`)
116
    dataToSearch.addDocuments(staffList)
117
    console.log(`staffList added - ${staffList.length} articles indexed`)
118
    dataToSearch.addDocuments(eventList)
119
    console.log(`eventList added - ${eventList.length} articles indexed`)
120
    this.setState({ search: dataToSearch, isLoading: false })
121
  }
122
  /**
123
   * handles the input change and perform a search with js-search
124
   * in which the results will be added to the state
125
   */
126
  searchData = e => {
127
    const { search } = this.state
128
    const queryResult = search.search(e.target.value)
129
130
    this.setState({ searchQuery: e.target.value, searchResults: queryResult })
131
  }
132
133
  handleSubmit = e => {
134
    e.preventDefault()
135
  }
136
137
  renderForm = searchQuery => (
138
    <form onSubmit={this.handleSubmit}>
139
      <div>
140
        <label className={"search_input__label"} htmlFor="search">
141
          <input
142
            id="search"
143
            onChange={this.searchData}
144
            className={"search_input__input"}
145
            placeholder="Spelersnaam, ploegnaam, deel van een artikel..."
146
            value={searchQuery}
147
            required
148
          />
149
          <span className={"search_input__label__inner_wrapper"}>
150
            <span className={"search_input__label__inner_text"}>
151
              Waar bent u naar op zoek?
152
            </span>
153
          </span>
154
        </label>
155
      </div>
156
    </form>
157
  )
158
159
  renderQueryResultsCaption = () => (
160
    <caption>
161
      <i
162
        className={`article__footer_related__icon article__footer_related__icon--node--article fa`}
163
      />{" "}
164
      Nieuwsbericht
165
      <br />
166
      <i
167
        className={`article__footer_related__icon article__footer_related__icon--node--team fa`}
168
      />{" "}
169
      Ploeg
170
      <br />
171
      <i
172
        className={`article__footer_related__icon article__footer_related__icon--node--player fa`}
173
      />{" "}
174
      Speler
175
      <br />
176
      <i
177
        className={`article__footer_related__icon article__footer_related__icon--node--staff fa`}
178
      />{" "}
179
      Staflid
180
      <br />
181
      <i
182
        className={`article__footer_related__icon article__footer_related__icon--node--event fa`}
183
      />{" "}
184
      Evenement
185
      <br />
186
    </caption>
187
  )
188
189
  renderQueryResultItem = item => (
190
    <tr key={`row_${item.attributes.drupal_internal__nid}`}>
191
      <td>
192
        <Link to={item.attributes.path.alias}>
193
          <i
194
            className={`article__footer_related__icon article__footer_related__icon--${item.type} fa`}
195
          />
196
          {item.attributes.title}
197
        </Link>
198
      </td>
199
    </tr>
200
  )
201
202
  renderQueryResults = queryResults => (
203
    <div>
204
      <h3>Gevonden resultaten: {queryResults.length}</h3>
205
      <table>
206
        <thead>
207
          <tr>
208
            <th>Titel</th>
209
          </tr>
210
        </thead>
211
        <tbody>
212
          {/* eslint-disable */}
213
          {queryResults.map(item => {
214
            return this.renderQueryResultItem(item)
215
          })}
216
          {/* eslint-enable */}
217
        </tbody>
218
        {this.renderQueryResultsCaption()}
219
      </table>
220
    </div>
221
  )
222
223
  render() {
224
    const { isError, isLoading, searchResults, searchQuery } = this.state
225
    const queryResults = searchQuery === `` ? [] : searchResults
226
227
    if (isLoading) {
228
      return <p>Zoekfunctie is aan het laden...</p>
229
    }
230
    if (isError) {
231
      return (
232
        <>
233
          <h2>Aiiii...</h2>
234
          <h3>
235
            Er ging iets mis - gelieve{" "}
236
            <a href="mailto:[email protected]">contact op te nemen</a>{" "}
237
            indien het probleem zich blijft voordoen.
238
          </h3>
239
        </>
240
      )
241
    }
242
243
    return (
244
      <div className={"search--placeholder"}>
245
        {this.renderForm(searchQuery)}
246
247
        {queryResults.length > 0 && this.renderQueryResults(queryResults)}
248
      </div>
249
    )
250
  }
251
}
252
export default Search
253